תוכנה נחמדה למשחק סודוקו שפתחתי
יש אפשרות ליצור ולפתור חידות - תהנו...
אפשר גם את קוד המקור כאן
תוכנה נחמדה למשחק סודוקו שפתחתי
יש אפשרות ליצור ולפתור חידות - תהנו...
אפשר גם את קוד המקור כאן
https://drive.google.com/file/d/1cZE1URPl3PP3OPcbBW6KBPeGyzqZ0ibY/view?usp=sharing
פיתחתי את זה לצורך אישי, ואני מאמין שזה יהיה שימושי לעוד אנשים - בעיקר למי שלא משתמש באינטרנט.
נ.ב. אני יודע שהתרגום לא מושלם, ונקטע במשפטים ארוכים, אבל לבנתיים זה מה שהצלחתי לאופליין, אם יש הצעות ייעול אני ישמח לשמוע.
לידיעתכם.
לפני כחודשיים גוגל הודיעה על הפסקת השירות של שליחה וקריאת מיילים באפליקציית צד שלישי עם שם משתמש וסיסמה, אפשר לראות כאן.
לתועלת כל מי שצריך, זה הדרך שאפשר לשלוח מיילים מתוכנה (שליחת log למייל, שליחת הודעה למשתמשים, וכד').
דבר ראשון לא צריך להפעיל את POP או IMAP, מומלץ להשאיר כבוי.
לפני הנפקת הסיסמא לאפליקציה צריך להפעיל את האימות הדו שלבי. נכנסים לחשבון, ותחת הלשונית 'אבטחה' לוחצים על 'אימות דו שלבי' ומבצעים את הפעולות.
הדרך שגוגל מספקת לקריאה/כתיבה של מיילים היא על ידי יצירת סיסמה ייעודית לאפליקציה. תחת הלשונית 'אבטחה' בוחרים ב 'סיסמאות לאפליקציות', נותנים את השם של האפליקציה (לזיכרון בעלמא) ולוחצים על 'צור', גוגל תיצור סיסמה באורך 16 תווים שבה צריך להשתמש כששולחים את המיילים דרך התוכנה.
היתרון הוא שאם מישהו עלה על הסיסמה שהוטמעה באפליקציה (עם decompiling למיניהם), הוא לא יוכל להיכנס לחשבון Google, ויהיה אפשרי אח"כ לבטל את הסיסמה.
@דאציג כתב בשיתוף | אב טיפוס של תוכנת תרגום אופליין:
רציתי להפנות את תשומת לבך, שיש תוכנת תמלול אופליין מבוססת AI (דורשת משאבים רבים), אמנם היא כעת בפיתוח, אבל - עובדת.
לא הכרתי, דווקא חיפשתי תוכנה כזאת לפני שהתחלתי לפתח.
בכל אופן התוכנה שהבאת משתמשת במודל התרגום NLLB-200 שזה מודל רב-לשוני של 200 שפות, ולכן הוא זולל הרבה משאבים (אצלי אני רואה 3.5 גיגה ראם בשימוש) שלא מתאימים למחשב רגיל
לפני שבחרתי את המודל תרגום לתוכנה בדקתי כמה מודלים, והסיבה שבחרתי את המודל הנוכחי (שנלקח מפה) היא בגלל שהוא דו-לשוני - לא זולל ראם, ותרגום יחסית בסדר (לא ראיתי מודלים שתרגמו יותר טוב).
בין המודלים שבדקתי:
SeamlessM4T ,MBART ,NLLB-200 ,M2M100
אם לא שמעתם על Avalonia אז כדי שתשמעו, זה הולך להיות הדור הבא של עיצוב אפליקציות דסקטופ עם ממשק גרפי בסביבת NET., הוא כבר נחשב ליורש המוצלח של wpf, אבל הבשורה הגדולה היא שהוא חוצה פלטפורמות לחלוטין, כלומר אתם יכולים לבנות ממשק משתמש פעם אחת ולקמפל אותו ל - Windows / macOS / Linux ועוד פלטפורמות (בלי צורך בפלטפורמת אינטרנט דוגמת Electron), מה שנותן את היתרון הגדול על wpf שכיום תואם רק ל-windows.
למי שמכיר את wpf זה ממש קל לעבור ל - Avalonia, ולמרות שהם מצהירים שהם לא מנסים לחקות את wpf הם ממש דומים, זה אותם שמות של פקדים וכולל כל הפיצ'רים של Markup כדוגמת: BindingExpression DynamicResourceExpression TemplateBindingExpression וכו'.
יש כמה שיפורים של דברים מעצבנים מ-wpf, לדוגמא הסטיילים ב-Avalonia עובדים בצורה אחרת שמזכירה עיצוב ב-css, יש סלקטורים וclassים שאיתם מחילים את הסגנונות. גם האנימציות עובדות בצורה יותר פשוטה (חסל Storyboards). קיים תיעוד למפתחי wpf.
כדי לעבוד עם ויז'ואל סטודיו צריך להתקין את ההרחבה Avalonia for Visual Studio 2022 ולפתוח פרויקט Avalonia חדש.
ואגב, לאילו המסופקים על הבשלות של הפרויקט, אז לפחות לטענת קהילת המפתחים הוא מספיק בשל ומוכן לייצור. יש רשימה של פרויקטים שמשתמשים עם Avalonia, אני לדוגמא אהבתי את זה Fluent Search
הפרויקט הוא חופשי ובקוד פתוח, יושב בgithub ונתמך על ידי NET Foundation.
אתר הבית: Avalonia UI - Home
@משתמש-מקצוען בסוף שיפרתי את זה והוספתי אפשרות של הדפסה, ועוד כמה דברים.
בהנאה: v2.1
@אוריי כתב בחלום \ אתגר | זיהוי ראשי תיבות של סימני מקורות בקבצי וורד:
יש ראשי תיבות סתמיים במסמך
אפשר לזהות ר"ת שהם לא יכולים להיות סימן ולהתעלם מהם.
לדוגמא: המילים אע"פ או שו"ת לא יכולים לייצג שום מספר בגימטרייה, אז זה ודאי ראשי תיבות שצריך להתעלם מהם.
אפשר לכתוב קוד שיזהה האם ר"ת כלשהוא יכול לייצג מספר או לא.
@בערל במיוחד בשבילך,
PrintUserLogger
תשים את שמות המשתמשים בקובץ users.txt בספרייה של התוכנה
תוכל לבצע שינויים בקוד המקור שנמצא ב-src (#C ו WPF)
בהצלחה!
אתה פיתחת? זה מרשים מאוד!
אכן. אני כתבתי את התוכנה.
למען האמת את מנוע החישוב של המהלכים לא אני פיתחתי, יש מנוע שחמט חזק שנכתב בשפת C, ואני השתמשתי בו (תוכל לראות ב-ProcessManager שיש תת תוכנה שרצה תחת התוכנה הראשית) בכל מהלך התוכנה שולחת לו את רצף המהלכים מתחילת המשחק והמנוע מחזיר את המהלך הכי טוב.
אבל הגרפיקה, הכללים של השחמט, המהלכים החוקיים - זה אני כתבתי.
תאמת שניסיתי לבנות מנוע שחמט עצמאי, אבל התייאשתי בגלל בעיות של ביצועים (לחישוב רק של 4 מהלכים לקח חצי דקה. הטכנולוגיה המועדפת בתוכנות שחמט היא בינה מלאכותית ולא חישוב יבש של כל המהלכים האפשריים. תחשבן שאם הממוצע של מהלכים אפשריים בכל תור הוא 25 מהלכים, עכשיו תעלה בחזקת 8 זה יוצא בערך 150 מיליארד מהלכים לניתוח. התוכנה לא עמדה בזה, בפרט שזה בטכנולוגיית NET. שגם ככה סובלת מבעיות ביצועים)
דרך אגב, המנוע הנ"ל הוא חזק מאוד, כמעט אין אפשרות לנצח אותו, אפילו ברמה נמוכה, ואפילו ברמה 1. כשנתתי לו לשחק מול עצמו, תמיד זה נגמר בתיקו.
@mekev אצלי במחשב יש בנתיב הרג'יסטרי הזה:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configuration\DELF06...\00
את הערכים PrimSurfSize.cx
ו - PrimSurfSize.cy
שמחזיקים את הערך של הרזולוציה של המסך, יכול להיות שאצלך החלק של הנתיב אחרי \Configuration\...
יהיה טיפה שונה, אז תבדוק שם.
נ.ב. איך הגעתי לזה? פשוט:
א. הרצתי Procmon
ב. סיננתי את כל הפעולות חוץ מ - RegSetValue
ג. פתחתי הגדרות, ושיניתי את הרזולוצייה.
ד. חזרתי ל - procmon ועברתי על הערכים שהשתנו.
יש ב-Avalonia המון טריקים ופיצ'רים מגניבים, שרק בגללם שווה לבחור אותו (אפילו רק לחלונות), ככל שאני חופר עוד בפרויקט אני מוקסם מהגאונות שטמונה בו (עז"נ חכמה בגויים תאמין), הנה כמה קסמי Binding של Avalonia באמצעות קוד #C:
var textBox = new TextBox
{
Width = 100,
};
var textBlock = new TextBlock
{
Width = 100,
[!TextBlock.TextProperty] = textBox[!TextBox.TextProperty]
};
באמצעות שורה 9 חיברתי את textBox.Text
עם textBlock.Text
, כמה פשוט וקל!
Select
:var textBox = new TextBox();
var text = textBox.GetObservable(TextBox.TextProperty);
var textBlock = new TextBlock
{
[!TextBlock.TextProperty] = text.Select(x => x + x).ToBinding()
};
Property
של פקד ישירות ל-Observable
כלשהו:var source = new Subject<string>();
var textBlock = new TextBlock();
textBlock.Bind(TextBlock.TextProperty, source.AsObservable());
source.OnNext("Next 1");
await Task.Delay(1000);
source.OnNext(" Next 2");
בכל פעם שיגיע ערך מה-Observable הטקסט של הפקד ישתנה לערך החדש.
עד כאן זה היה בקוד #C, גם בתחביר xaml יש עוד המון פיצ'רים הנה כמה לדוגמא:
!
:{Binding MyProperty}
{Binding !MyProperty}
<TextBox Name="tb">
<TextBlock Text="{Binding #tb.Text}"/>
parent$
:<Border Tag="Hello World!">
<TextBlock Text="{Binding $parent.Tag}"/>
</Border>
אפשר גם באמצעות אינדקס:
<Border Tag="Hello World!">
<Border>
<TextBlock Text="{Binding $parent[1].Tag}"/>
</Border>
</Border>
ואפשר גם באמצעות הטייפ:
<Border Tag="Hello World!">
<Decorator>
<TextBlock Text="{Binding $parent[Border].Tag}"/>
</Decorator>
</Border>
ואפשר גם באמצעות טייפ ואינדקס:
<Border Tag="Hello World!">
<Border>
<Decorator>
<TextBlock Text="{Binding $parent[Border;1].Tag}"/>
</Decorator>
</Border>
</Border>
^
:// ViewModel
public IObservable<string> Name {get; set; }
// xaml
<TextBlock Text="{Binding Name^.Length}"/>
// ViewModel
public Task<string> MyAsyncText => GetTextAsync();
private async Task<string> GetTextAsync()
{
await Task.Delay(1000); // The delay is just for demonstration purpose
return "Hello from async operation";
}
// xaml
<TextBlock Text="{Binding MyAsyncText^, FallbackValue='Wait a second'}" />
בקיצור, תן לחכם ויחכם עוד, יש עוד הרבה דוגמאות שאפשר לראות בתיעוד.
יש הרבה סיבות טובות לבחור ב-Avalonia.
יש דרך פשוטה ונחמדה (שאולי אתם כבר מכירים) להצפנה סימטרית בסיסית, באמצעות xor:
דוגמא קטנה:
בחרו מספר שהוא יהיה ה'מפתח', בשביל הדוגמא נבחר במספר: 613.
בחרו מספר שאותו תרצו להצפין, לצורך הדוג' ניקח את המספר 234.
עכשיו נבצע xor (במחשבון מדעי או ב'מצב מתכנת' זה הסימון ^) על שני המספרים באמצעות התרגיל:
613 ^ 234, והתוצאה היא: 655. יופי, זהו המספר המוצפן.
עכשיו כדי לפענח אותו בחזרה נעשה את אותה הפעולה שוב עם המספר המוצפן:
613 ^ 655, והתוצאה היא: 234!
בדרך הזאת אפשר להצפין מספרים וטקסטים, לא משהו מאוד מאובטח, אבל ממש נחמד. גם מי שידע באיזה דרך עשינו את ההצפנה לא יוכל לעלות על המספר המקורי מבלי שידע את המספר ה'מפתח' שאתו עשינו את ההצפנה.
@pcinfogmach כתב בעזרה עם בעיה בהתחברות לגיטהב:
לפי מה שכתוב שם המתקין החדש אמור לטפל בזה באופן אוטומטי
כנראה שזה אמור לטפל באופן אוטומטי רק אם מותקן לך גיט, וכנראה שלא מותקן לך גיט באופן גלובאלי, (ויז'ואל סטודיו מאחסן את הבינאריים של גיט באיזשהו תיקיה במחשב וניגש אליהם באופן ישיר)
אז אפשרות אחת שתתקין גיט מכאן, ואח"כ תריץ git clone https://github/???.git
עם הלינק של המאגר (כמובן אחרי ההתקנה של התעודה)
ואפשרות שניה שתבצע את מה שכתוב כאן תחת הכותרת: שימוש ב github desktop או בgit דרך תוכנות מסוימות למשל visual studio, ואגב, אם מותקן לך Everything זה יהיה יותר קל למצוא את הנתיב של git, פשוט תחפש git.exe
הרעיון בגדול זה שאם מפעילים ישירות את הסקריפט זה מריץ את מה שבתוך התנאי, אבל אם עושים לו import מסקריפט אחר אז הוא לא מריץ את זה.
למה זה שימושי?
נניח שיש סקריפט שמכיל כמה פונקציות ומבצע פעולה מסויימת כשמריצים אותו, עכשיו אם משהו ירצה להשתמש רק בפונקציות של הסקריפט מבלי לבצע את הפעולה שהסקריפט עושה, אז כשהוא יעשה import כל הסקריפט עצמו ירוץ, דבר שהוא לא רוצה.
לכן בדרך כלל מכניסים את הפוקציה הראשית לתוך התנאי הזה, כך שהיא תתבצע רק אם הפעילו את הסקריפט עצמו ולא אם עשו לו import מסקריפט אחר.
@dovid כתב ברוזולציה בהמרת pdf לתמונה:
ז. ללחוץ על קובץ הPDF בימני של העבר תוך החזקת SHIFT ולבחור בהעתק נתיב
ח. שוב בשורת הפקודה ללחוץ על הימני בעכבר לשם הדבקת הנתיב.
אפשר גם לגרור ישירות לקונסול.
@pcinfogmach
במקום:
return string.Join("\n", nonEmptyLines);
עדיף:
return string.Join(Environment.NewLine, nonEmptyLines);
אני הייתי עושה את זה גם בשורה הראשונה במקום: new[] { '\r', '\n' }
בדיוק לפני כמה זמן הייתי צריך לכתוב קוד שמחלץ תמונה ממוזערת מקובץ וידיאו, אז כתבתי את זה (וזה מתאים לכל סוגי הקבצים, גם לכוננים), היתרון שאפשר לקבל את התמונה בגודל שתרצה ועם עוד enum של אפשרויות.
זה הקוד:
public static class Shell
{
private static readonly Guid _s_imageFactoryShellId = new("BCC18B79-BA16-442F-80C4-8A59C30C463B");
public static byte[] GetImage(string path, ImageSize size, ShellItemGetImageOptions options)
{
if (OperatingSystem.IsWindows())
{
if (SHCreateItemFromParsingName(path, 0, _s_imageFactoryShellId, out var imageFactory) != 0)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
if (imageFactory.GetImage(size, (int)options, out var hBitmap) != 0)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try
{
using var stream = new MemoryStream();
var bitmap = Image.FromHbitmap(hBitmap);
bitmap.Save(stream, ImageFormat.Jpeg);
return stream.ToArray();
}
finally
{
DeleteObject(hBitmap);
}
}
throw new PlatformNotSupportedException();
}
}
public enum ShellItemGetImageOptions
{
ResizeToFit = 0,
BiggerSizeOk = 1,
MemoryOnly = 2,
IconOnly = 4,
ThumbnailOnly = 8,
InCacheOnly = 0x10,
CropToSquare = 0x20,
WideThumbnails = 0x40,
IconBackground = 0x80,
ScaleUp = 0x100
}
public readonly struct ImageSize(int width, int height)
{
public int Width { get; } = width;
public int Height { get; } = height;
}
internal static partial class Unmanaged
{
[GeneratedComInterface]
[Guid("BCC18B79-BA16-442F-80C4-8A59C30C463B")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public partial interface IShellItemImageFactory
{
[PreserveSig]
int GetImage(ImageSize size, int flags, out nint hBitmap);
}
[LibraryImport("Shell32", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
public static partial int SHCreateItemFromParsingName(string pszPath, nint pbc, Guid riid, out IShellItemImageFactory ppv);
[LibraryImport("Gdi32", SetLastError = true)]
public static partial int DeleteObject(nint hObject);
}
נ.ב.
זה הקוד הבסיסי, אפשר לשנות ולהתאים אותו למה שאתה צריך.
לא בדקתי אם זה עובד גם על מערכות windows יותר ישנות.
הקוד תואם ל NativeAOT (אם תשתמש בו בעתיד)
לא יודע אם הקוד הזה יעבוד ב net-framework.
לאחר הרבה ניסיונות מצאתי בס"ד את הדרך ליישם את זה, אני שם את זה פה אם למישהו זה יהיה שימושי בעתיד.
א. הוספתי מחלקת עזר שתייצר ממשקי COM כדלהלן:
public static partial class ComActivator
{
[LibraryImport("ole32")]
private static partial int CoCreateInstance(
ref Guid clsid,
nint pUnkOuter,
int dwClsContext,
ref Guid iid,
[MarshalAs(UnmanagedType.Interface)] out object pObj
);
public static TInterface ActivateClass<TInterface>(Guid clsid, Guid iid)
{
Debug.Assert(iid == typeof(TInterface).GUID);
var hResult = CoCreateInstance(ref clsid, default, 1, ref iid, out var obj);
if (hResult < 0)
{
Marshal.ThrowExceptionForHR(hResult);
}
return (TInterface)obj;
}
}
ב. למחלקה ITaskbarList3
הוספתי את התכונה GeneratedComInterface
ג. ככה אני מקבל את האובייקט:
var clsid = Guid.Parse("56FDF344-FD6D-11D0-958A-006097C9A090"); // TaskBarList
var iid = Guid.Parse("EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF"); // ITaskBarList3
var taskbar = ComActivator.ActivateClass<ITaskbarList3>(clsid, iid);
קישור שעזר לי: https://learn.microsoft.com/en-us/dotnet/standard/native-interop/tutorial-comwrappers
נ.ב. מצאתי עוד פתרון עם ComWrappers
אבל הפתרון הראשון עובד מצויין אז השתמשתי בו.